
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Xml;
	
namespace Swaf.BizObj.xml
{
	/// <summary> Maintains a <c>System.Xml.XmlElement</c> and an xpath <c>String</c> that 
	/// returns a <c>System.Xml.XmlNodeList</c> for use by <c>XmlBusinessObjectIList</c>.</summary>
	[Serializable]
	public class ListState
	{
		private string m_xpath;
		private XmlNodeList m_nodeList;
		private bool m_insertIntoBase;

		//Either this ListState object is using m_baseEl
		private XmlElement m_baseEl;
		//or it using a parent name and IXmlNodeParent
		private string m_name;
		private IXmlNodeParent m_parent;

		private int m_cursorPos;
		private IEnumerator m_cursor;

		/// <summary>Creates a new instance of IListState</summary>
		public ListState(string name, IXmlNodeParent parent, string xpath)
			:this(null, xpath, true)
		{
			m_name = name;
			m_parent = parent;
		}

		public ListState(XmlElement baseEl, string xpath)
			:this(baseEl, xpath, false)
		{
		}
		
		/// <summary>Creates a new instance of IListState 
		/// </summary>
		public ListState(XmlElement baseEl, string xpath, bool insertIntoBase)
		{
			m_baseEl = baseEl;
			m_xpath = xpath;
			m_insertIntoBase = insertIntoBase;
			refresh();
		}
		
		public virtual void  refresh()
		{
			if(BaseEl != null)
				if(m_xpath == "~")
					m_nodeList = BaseEl.ChildNodes;
#if(!COMPACT_FRAMEWORK)
				else
					m_nodeList = BaseEl.SelectNodes(m_xpath);
#endif
			if(m_nodeList != null)
			{
				m_cursor = m_nodeList.GetEnumerator();
				m_cursorPos = 0;
			}
		}
		
		public virtual string objNodeName()
		{
			string name = "";
			int index;
			if ((index = m_xpath.LastIndexOf((System.Char) '/')) != - 1)
				name = m_xpath.Substring(index + 1);
			else
				name = m_xpath;
			
			if ((index = name.IndexOf((System.Char) '[')) != - 1)
				name = name.Substring(0, (index) - (0));
			if(name.IndexOfAny(new char[]{'*','.','~'}) != -1)
				return "";
			
			return name;
		}

		public virtual XmlElement this[int pos]
		{
			get
			{
				if(m_cursorPos > pos)
				{
					m_cursor.Reset();
					m_cursorPos = 0;
				}
				while(m_cursorPos < pos)
				{
					m_cursor.MoveNext();
					++m_cursorPos;
				}
				return (XmlElement)m_cursor.Current;
			}
		}
		
		public virtual XmlNodeList list
		{get{
			return m_nodeList;
		}}

		public virtual bool InsertIntoBase
		{get{
			return m_insertIntoBase;
		}}

		public virtual XmlElement getForceBaseEl()
		{
			 if(m_baseEl != null)
				return m_baseEl;
			 else if(m_parent != null)
				 return m_parent.getChildElement(m_name, true);
			 else
				 return null;			
		}

		public virtual XmlElement BaseEl
		{get{
			 if(m_baseEl != null)
				return m_baseEl;
			 else if(m_parent != null)
				 return m_parent.getChildElement(m_name, false);
			 else
				 return null;
		}}
		
	}
}